module KScheme
  module Scheme
    include Treetop::Runtime

    def root
      @root || :expression
    end

    module Expression0
      def exp
        elements[1]
      end

    end

    module Expression1
      def value
        exp.value
      end
    end

    def _nt_expression
      start_index = index
      if node_cache[:expression].has_key?(index)
        cached = node_cache[:expression][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0, s0 = index, []
      s1, i1 = [], index
      loop do
        r2 = _nt_space
        if r2
          s1 << r2
        else
          break
        end
      end
      r1 = SyntaxNode.new(input, i1...index, s1)
      s0 << r1
      if r1
        i3 = index
        r4 = _nt_atom
        if r4
          r3 = r4
        else
          r5 = _nt_quoted
          if r5
            r3 = r5
          else
            r6 = _nt_list
            if r6
              r3 = r6
            else
              r7 = _nt_cons
              if r7
                r3 = r7
              else
                self.index = i3
                r3 = nil
              end
            end
          end
        end
        s0 << r3
        if r3
          s8, i8 = [], index
          loop do
            r9 = _nt_space
            if r9
              s8 << r9
            else
              break
            end
          end
          r8 = SyntaxNode.new(input, i8...index, s8)
          s0 << r8
        end
      end
      if s0.last
        r0 = (SyntaxNode).new(input, i0...index, s0)
        r0.extend(Expression0)
        r0.extend(Expression1)
      else
        self.index = i0
        r0 = nil
      end

      node_cache[:expression][start_index] = r0

      return r0
    end

    def _nt_atom
      start_index = index
      if node_cache[:atom].has_key?(index)
        cached = node_cache[:atom][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0 = index
      r1 = _nt_number
      if r1
        r0 = r1
      else
        r2 = _nt_string
        if r2
          r0 = r2
        else
          r3 = _nt_symbol
          if r3
            r0 = r3
          else
            self.index = i0
            r0 = nil
          end
        end
      end

      node_cache[:atom][start_index] = r0

      return r0
    end

    def _nt_number
      start_index = index
      if node_cache[:number].has_key?(index)
        cached = node_cache[:number][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0 = index
      r1 = _nt_decimal
      if r1
        r0 = r1
      else
        r2 = _nt_integer
        if r2
          r0 = r2
        else
          self.index = i0
          r0 = nil
        end
      end

      node_cache[:number][start_index] = r0

      return r0
    end

    module Integer0
    end

    module Integer1
    end

    module Integer2
      def value
        text_value.to_i
      end
    end

    def _nt_integer
      start_index = index
      if node_cache[:integer].has_key?(index)
        cached = node_cache[:integer][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0, s0 = index, []
      if input.index(/[-+]/, index) == index
        r2 = (SyntaxNode).new(input, index...(index + 1))
        @index += 1
      else
        r2 = nil
      end
      if r2
        r1 = r2
      else
        r1 = SyntaxNode.new(input, index...index)
      end
      s0 << r1
      if r1
        i3 = index
        i4, s4 = index, []
        if input.index(/[1-9]/, index) == index
          r5 = (SyntaxNode).new(input, index...(index + 1))
          @index += 1
        else
          r5 = nil
        end
        s4 << r5
        if r5
          s6, i6 = [], index
          loop do
            if input.index(/[0-9]/, index) == index
              r7 = (SyntaxNode).new(input, index...(index + 1))
              @index += 1
            else
              r7 = nil
            end
            if r7
              s6 << r7
            else
              break
            end
          end
          r6 = SyntaxNode.new(input, i6...index, s6)
          s4 << r6
        end
        if s4.last
          r4 = (SyntaxNode).new(input, i4...index, s4)
          r4.extend(Integer0)
        else
          self.index = i4
          r4 = nil
        end
        if r4
          r3 = r4
        else
          if input.index('0', index) == index
            r8 = (SyntaxNode).new(input, index...(index + 1))
            @index += 1
          else
            terminal_parse_failure('0')
            r8 = nil
          end
          if r8
            r3 = r8
          else
            self.index = i3
            r3 = nil
          end
        end
        s0 << r3
      end
      if s0.last
        r0 = (SyntaxNode).new(input, i0...index, s0)
        r0.extend(Integer1)
        r0.extend(Integer2)
      else
        self.index = i0
        r0 = nil
      end

      node_cache[:integer][start_index] = r0

      return r0
    end

    module Decimal0
    end

    module Decimal1
      def value
        text_value.to_f
      end
    end

    def _nt_decimal
      start_index = index
      if node_cache[:decimal].has_key?(index)
        cached = node_cache[:decimal][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0, s0 = index, []
      if input.index(/[-+]/, index) == index
        r2 = (SyntaxNode).new(input, index...(index + 1))
        @index += 1
      else
        r2 = nil
      end
      if r2
        r1 = r2
      else
        r1 = SyntaxNode.new(input, index...index)
      end
      s0 << r1
      if r1
        s3, i3 = [], index
        loop do
          if input.index(/[0-9]/, index) == index
            r4 = (SyntaxNode).new(input, index...(index + 1))
            @index += 1
          else
            r4 = nil
          end
          if r4
            s3 << r4
          else
            break
          end
        end
        if s3.empty?
          self.index = i3
          r3 = nil
        else
          r3 = SyntaxNode.new(input, i3...index, s3)
        end
        s0 << r3
        if r3
          if input.index('.', index) == index
            r5 = (SyntaxNode).new(input, index...(index + 1))
            @index += 1
          else
            terminal_parse_failure('.')
            r5 = nil
          end
          s0 << r5
          if r5
            s6, i6 = [], index
            loop do
              if input.index(/[0-9]/, index) == index
                r7 = (SyntaxNode).new(input, index...(index + 1))
                @index += 1
              else
                r7 = nil
              end
              if r7
                s6 << r7
              else
                break
              end
            end
            if s6.empty?
              self.index = i6
              r6 = nil
            else
              r6 = SyntaxNode.new(input, i6...index, s6)
            end
            s0 << r6
          end
        end
      end
      if s0.last
        r0 = (SyntaxNode).new(input, i0...index, s0)
        r0.extend(Decimal0)
        r0.extend(Decimal1)
      else
        self.index = i0
        r0 = nil
      end

      node_cache[:decimal][start_index] = r0

      return r0
    end

    module String0
    end

    module String1
      def content
        elements[1]
      end

    end

    module String2
      def value
        content.text_value
      end
    end

    def _nt_string
      start_index = index
      if node_cache[:string].has_key?(index)
        cached = node_cache[:string][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0, s0 = index, []
      if input.index('"', index) == index
        r1 = (SyntaxNode).new(input, index...(index + 1))
        @index += 1
      else
        terminal_parse_failure('"')
        r1 = nil
      end
      s0 << r1
      if r1
        s2, i2 = [], index
        loop do
          i3 = index
          i4, s4 = index, []
          if input.index('\\', index) == index
            r5 = (SyntaxNode).new(input, index...(index + 1))
            @index += 1
          else
            terminal_parse_failure('\\')
            r5 = nil
          end
          s4 << r5
          if r5
            if index < input_length
              r6 = (SyntaxNode).new(input, index...(index + 1))
              @index += 1
            else
              terminal_parse_failure("any character")
              r6 = nil
            end
            s4 << r6
          end
          if s4.last
            r4 = (SyntaxNode).new(input, i4...index, s4)
            r4.extend(String0)
          else
            self.index = i4
            r4 = nil
          end
          if r4
            r3 = r4
          else
            if input.index(/[^"]/, index) == index
              r7 = (SyntaxNode).new(input, index...(index + 1))
              @index += 1
            else
              r7 = nil
            end
            if r7
              r3 = r7
            else
              self.index = i3
              r3 = nil
            end
          end
          if r3
            s2 << r3
          else
            break
          end
        end
        r2 = SyntaxNode.new(input, i2...index, s2)
        s0 << r2
        if r2
          if input.index('"', index) == index
            r8 = (SyntaxNode).new(input, index...(index + 1))
            @index += 1
          else
            terminal_parse_failure('"')
            r8 = nil
          end
          s0 << r8
        end
      end
      if s0.last
        r0 = (SyntaxNode).new(input, i0...index, s0)
        r0.extend(String1)
        r0.extend(String2)
      else
        self.index = i0
        r0 = nil
      end

      node_cache[:string][start_index] = r0

      return r0
    end

    module Symbol0
    end

    module Symbol1
      def value
        text_value.to_sym
      end
    end

    def _nt_symbol
      start_index = index
      if node_cache[:symbol].has_key?(index)
        cached = node_cache[:symbol][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0 = index
      if input.index(/[-+*\/]/, index) == index
        r1 = (SyntaxNode).new(input, index...(index + 1))
        @index += 1
      else
        r1 = nil
      end
      if r1
        r0 = r1
        r0.extend(Symbol1)
      else
        i2, s2 = index, []
        if input.index(/[a-zA-Z]/, index) == index
          r3 = (SyntaxNode).new(input, index...(index + 1))
          @index += 1
        else
          r3 = nil
        end
        s2 << r3
        if r3
          s4, i4 = [], index
          loop do
            if input.index(/[-_a-zA-Z0-9]/, index) == index
              r5 = (SyntaxNode).new(input, index...(index + 1))
              @index += 1
            else
              r5 = nil
            end
            if r5
              s4 << r5
            else
              break
            end
          end
          r4 = SyntaxNode.new(input, i4...index, s4)
          s2 << r4
          if r4
            if input.index(/[!?]/, index) == index
              r7 = (SyntaxNode).new(input, index...(index + 1))
              @index += 1
            else
              r7 = nil
            end
            if r7
              r6 = r7
            else
              r6 = SyntaxNode.new(input, index...index)
            end
            s2 << r6
          end
        end
        if s2.last
          r2 = (SyntaxNode).new(input, i2...index, s2)
          r2.extend(Symbol0)
        else
          self.index = i2
          r2 = nil
        end
        if r2
          r0 = r2
          r0.extend(Symbol1)
        else
          self.index = i0
          r0 = nil
        end
      end

      node_cache[:symbol][start_index] = r0

      return r0
    end

    def _nt_space
      start_index = index
      if node_cache[:space].has_key?(index)
        cached = node_cache[:space][index]
        @index = cached.interval.end if cached
        return cached
      end

      if input.index(/[ \n\t]/, index) == index
        r0 = (SyntaxNode).new(input, index...(index + 1))
        @index += 1
      else
        r0 = nil
      end

      node_cache[:space][start_index] = r0

      return r0
    end

    module Cons0
      def exp1
        elements[1]
      end

      def exp2
        elements[3]
      end

    end

    module Cons1
      def value
        Cons.new(exp1.value, exp2.value)
      end
    end

    def _nt_cons
      start_index = index
      if node_cache[:cons].has_key?(index)
        cached = node_cache[:cons][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0, s0 = index, []
      if input.index('(', index) == index
        r1 = (SyntaxNode).new(input, index...(index + 1))
        @index += 1
      else
        terminal_parse_failure('(')
        r1 = nil
      end
      s0 << r1
      if r1
        r2 = _nt_expression
        s0 << r2
        if r2
          if input.index('.', index) == index
            r3 = (SyntaxNode).new(input, index...(index + 1))
            @index += 1
          else
            terminal_parse_failure('.')
            r3 = nil
          end
          s0 << r3
          if r3
            r4 = _nt_expression
            s0 << r4
            if r4
              if input.index(')', index) == index
                r5 = (SyntaxNode).new(input, index...(index + 1))
                @index += 1
              else
                terminal_parse_failure(')')
                r5 = nil
              end
              s0 << r5
            end
          end
        end
      end
      if s0.last
        r0 = (SyntaxNode).new(input, i0...index, s0)
        r0.extend(Cons0)
        r0.extend(Cons1)
      else
        self.index = i0
        r0 = nil
      end

      node_cache[:cons][start_index] = r0

      return r0
    end

    module List0
      def list
        elements[1]
      end

    end

    module List1
      def value
        list.elements.reverse.inject(nil) { |list, elem|
          Cons.new(elem.value, list)
        }
      end
    end

    def _nt_list
      start_index = index
      if node_cache[:list].has_key?(index)
        cached = node_cache[:list][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0, s0 = index, []
      if input.index('(', index) == index
        r1 = (SyntaxNode).new(input, index...(index + 1))
        @index += 1
      else
        terminal_parse_failure('(')
        r1 = nil
      end
      s0 << r1
      if r1
        s2, i2 = [], index
        loop do
          r3 = _nt_expression
          if r3
            s2 << r3
          else
            break
          end
        end
        r2 = SyntaxNode.new(input, i2...index, s2)
        s0 << r2
        if r2
          if input.index(')', index) == index
            r4 = (SyntaxNode).new(input, index...(index + 1))
            @index += 1
          else
            terminal_parse_failure(')')
            r4 = nil
          end
          s0 << r4
        end
      end
      if s0.last
        r0 = (SyntaxNode).new(input, i0...index, s0)
        r0.extend(List0)
        r0.extend(List1)
      else
        self.index = i0
        r0 = nil
      end

      node_cache[:list][start_index] = r0

      return r0
    end

    module Quoted0
      def expression
        elements[1]
      end
    end

    module Quoted1
      def value
        Cons.new(:quote, Cons.new(expression.value, nil))
      end
    end

    def _nt_quoted
      start_index = index
      if node_cache[:quoted].has_key?(index)
        cached = node_cache[:quoted][index]
        @index = cached.interval.end if cached
        return cached
      end

      i0, s0 = index, []
      if input.index("'", index) == index
        r1 = (SyntaxNode).new(input, index...(index + 1))
        @index += 1
      else
        terminal_parse_failure("'")
        r1 = nil
      end
      s0 << r1
      if r1
        r2 = _nt_expression
        s0 << r2
      end
      if s0.last
        r0 = (SyntaxNode).new(input, i0...index, s0)
        r0.extend(Quoted0)
        r0.extend(Quoted1)
      else
        self.index = i0
        r0 = nil
      end

      node_cache[:quoted][start_index] = r0

      return r0
    end

  end

  class SchemeParser < Treetop::Runtime::CompiledParser
    include Scheme
  end

end

# Local Variables:
# indent-tabs-mode: nil
# End:
